package com.rednote.config;

import com.rednote.common.JwtUtil;
import com.rednote.common.UserContextHolder;
import com.rednote.service.UsersService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final StringRedisTemplate redisTemplate;
    private final JwtUtil jwtUtil;
    private final UsersService usersService;

    public JwtAuthenticationFilter(JwtUtil jwtUtil, UsersService usersService, StringRedisTemplate redisTemplate) {
        this.jwtUtil = jwtUtil;
        this.usersService = usersService;
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            filterChain.doFilter(request, response);
            return;
        }

        try{
        String token = extractToken(request);
        
        if (token != null 
            && jwtUtil.validateToken(token) 
            && redisTemplate.opsForValue().get("blacklist:" + token) == null) {
            
            var claims = jwtUtil.parseToken(token);
            Integer userId = ((Number) claims.get("userId")).intValue();
            String account = claims.get("account", String.class);
            /**
             * 设置用户ID到线程上下文中，以便在后续的业务逻辑中使用
             *
             * @author wzy
             * @since 2025-06-03
             */
            UserContextHolder.setUserId(userId);

            // 获取用户的角色和权限
            List<String> authorities = usersService.getUserAuthorities(userId);
            
            var authentication = new UsernamePasswordAuthenticationToken(
                account,
                null,
                authorities.stream()
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList())
            );
            
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        
        filterChain.doFilter(request, response);
            /**
             * 清除线程上下文中的用户ID
             *
             * @author wzy
             * @since 2025-06-03
             */
        } finally {
            // 一定要清除 ThreadLocal，防止内存泄漏
            UserContextHolder.clear();
        }
    }
    
    private String extractToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
} 